package com.wx.infrastructure.domain.dto;

import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.wx.infrastructure.domain.ErrorCode;
import com.wx.infrastructure.enums.ErrorCodeEnum;
import lombok.Data;

import java.util.Objects;

/**
 * wx_back_end
 *
 * @Auther: cheng.tang
 * @Date: 2023/2/28 10:01 PM
 * @Description:
 */
@Data
public class ResultDTO<T> implements ErrorCode {

    @JSONField(serialize = false, deserialize = false)
    @JsonIgnore
    private transient ErrorCode errorCode;

    private Integer code;

    private String msg;

    private T data;

    private Boolean success;

    /**
     * 成功的请求
     *
     * @param <T>
     * @return
     */
    public static <T> ResultDTO<T> ok() {
        ResultDTO<T> resultDTO = new ResultDTO<>();
        resultDTO.setErrorCode(ErrorCodeEnum.SUCCESS);
        return resultDTO;
    }

    /**
     * 成功的请求
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultDTO<T> ok(T data) {
        ResultDTO<T> resultDTO = ok();
        resultDTO.setData(data);
        return resultDTO;
    }

    /**
     * 异常的请求
     *
     * @param errorCode
     * @param <T>
     * @return
     */
    public static <T> ResultDTO<T> fail(ErrorCode errorCode) {
        ResultDTO<T> resultDTO = new ResultDTO<>();
        resultDTO.setErrorCode(errorCode);
        return resultDTO;
    }

    /**
     * 异常的请求
     *
     * @return
     */
    public static ResultDTO<String> fail() {
        return fail(ErrorCodeEnum.FAIL.setMsg("未知异常"));
    }

    /**
     * 异常的请求
     *
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> ResultDTO<T> fail(String msg) {
        return fail(ErrorCodeEnum.FAIL.setMsg(msg));
    }

    /**
     * 异常的请求，有返回数据
     *
     * @param errorCode
     * @param data
     * @return
     */
    public static <T> ResultDTO<T> fail(ErrorCode errorCode, T data) {
        ResultDTO<T> resultDTO = fail(errorCode);
        resultDTO.setData(data);
        return resultDTO;
    }

    public void setErrorCode(ErrorCode errorCode) {
        this.errorCode = errorCode;
        if (errorCode != null) {
            this.setCode(errorCode.getCode());
            this.msg = errorCode.getMsg();
            this.success = Objects.equals(this.errorCode, ErrorCodeEnum.SUCCESS);
        }
    }


    @Override
    public Integer getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }

    @Override
    public ErrorCode setMsg(String msg) {
        this.msg = msg;
        return errorCode;
    }


}
